package com.young.launch_task_init.core

import android.app.Application
import com.young.launch_task_init.core.dispatcher.DefaultTaskDispatcher
import com.young.launch_task_init.core.dispatcher.ITaskDispatcher
import com.young.launch_task_init.core.group.BaseTaskGroup
import com.young.launch_task_init.core.listener.OnCompletedListener
import com.young.launch_task_init.core.log.ILog
import com.young.launch_task_init.core.log.SimpleLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

/**
 * Author：young
 * .
 * Time： 31/3/2023 上午10:07 周五
 * .
 * Desc：初始化任务管理器
 */
class InitManager {

    companion object {

        /**
         * 获取一个构建器
         *
         * @param application 应用程序上下文
         * @param onCompleteListener 完成监听
         */
        fun builder(application: Application, onCompleteListener: OnCompletedListener): Builder {
            return Builder(application, onCompleteListener)
        }
    }

    // 应用程序上下文
    lateinit var application: Application

    // 任务分发器
    lateinit var taskDispatcher: ITaskDispatcher

    // 任务组集合
    lateinit var taskGroupList: List<BaseTaskGroup<*>>

    // 完成监听
    lateinit var onCompletedListener: OnCompletedListener

    /** 懒加载的完成监听 **/
    var onLazyCompletedListener: OnCompletedListener? = null

    /** 日志类 **/
    var log: ILog = SimpleLog

    /** 是否开启日志打印 **/
    var isShowLog = false

    /**
     * 开始执行初始化任务
     */
    fun start() {
        GlobalScope.launch(Dispatchers.IO) {
            taskDispatcher.dispatchTasks(this, taskGroupList, this@InitManager)
        }
    }

    /**
     * 构建者
     * @param application 应用程序上下文
     */
    class Builder(application: Application, onCompleteListener: OnCompletedListener) {

        // 参数
        private val P = InitManagerParams(application, onCompleteListener)

        /**
         * 设置任务调度器
         *
         * 备注：可以不设置，有默认值
         */
        fun setTaskDispatcher(taskDispatcher: ITaskDispatcher): Builder {
            P.taskDispatcher = taskDispatcher
            return this
        }


        /**
         * 设置日志输出类
         *
         * 备注：可以不设置，有默认实现
         */
        fun setLog(log: ILog): Builder {
            P.log = log
            return this
        }

        /**
         * 设置日志显示
         */
        fun setShowLog(isShow: Boolean): Builder {
            P.isShowLog = isShow
            return this
        }

        /**
         * 设置懒加载的完成监听
         * @param listener 懒加载的完成监听
         */
        fun setOnLazyCompletedListener(listener: OnCompletedListener): Builder {
            P.onLazyCompletedListener = listener
            return this
        }

        /**
         * 添加任务组(内部按照任务顺序执行)
         * @param group 任务组
         */
        fun addTaskGroup(group: BaseTaskGroup<*>): Builder {
            P.taskGroupList.add(group)
            return this
        }

        /**
         * 构建 InitManager 对象
         */
        fun build(): InitManager {
            val manager = InitManager()
            P.apply(manager)
            return manager
        }
    }

    /**
     * InitManager 的参数
     *
     * @param application 应用程序上下文
     * @param onCompletedListener 完成监听
     */
    private class InitManagerParams(
        val application: Application,
        val onCompletedListener: OnCompletedListener
    ) {
        /** 任务分发器 **/
        var taskDispatcher: ITaskDispatcher = DefaultTaskDispatcher()

        /** 任务组集合 **/
        val taskGroupList = mutableListOf<BaseTaskGroup<*>>()

        /** 懒加载的完成监听 **/
        var onLazyCompletedListener: OnCompletedListener? = null

        /** 日志类 **/
        var log: ILog = SimpleLog

        /** 是否开启日志打印 **/
        var isShowLog = false

        /**
         * 为 InitManager 填充参数
         */
        fun apply(manager: InitManager) {
            manager.application = application
            manager.taskDispatcher = taskDispatcher
            manager.taskGroupList = taskGroupList
            manager.onCompletedListener = onCompletedListener
            manager.onLazyCompletedListener = onLazyCompletedListener
            manager.log = log
            manager.isShowLog = isShowLog
        }
    }


}